package server;

import java.io.IOException;
import java.net.SocketException;
import java.util.Collection;
import java.util.concurrent.ConcurrentLinkedQueue;

import util.Connection;
import util.Network;

import messages.DHResponseMessage;
import messages.Message;

public class SendThread implements Runnable {
	private ConcurrentLinkedQueue<MessageInfo> sendQ;
	private Collection<Connection> connections;
	
	public SendThread(ConcurrentLinkedQueue<MessageInfo> sendQ, Collection<Connection> connections) {
		this.sendQ = sendQ;
		this.connections = connections;
	}

	public void run() {
		for(;;) {
			
			while(sendQ.isEmpty()) {
				synchronized(sendQ) {
					try {
						sendQ.wait();
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
			
			
			MessageInfo mp = sendQ.poll();
			Message m = mp.getMessage();
			
			try {
				byte[] bytes = Network.serialize(m);
				//System.out.println("Decr bytes to send: " + Network.toHexString(bytes));
				if(mp.getConnection().getKey() != null && !(m instanceof DHResponseMessage)) {
					//System.out.println("Encoding with key: "+ Network.toHexString(mp.getConnection().getKey().getEncoded()));
					bytes = Network.encrypt(mp.getConnection().getKey(), bytes);
					//System.out.println("Sending bytes: " + Network.toHexString(bytes));
				}
				Network.sendBytes(mp.getSocket(), bytes);
			} catch (SocketException se) {
				//happens on logout: broken pipe
				if(se.getMessage().equals("broken pipe")) {
					connections.remove(mp.getConnection());
				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			
			
		}
	}

}
